package com.qf.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.Configuration;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionManager;

import javax.sql.DataSource;
import java.util.Properties;

@Component
@PropertySource("classpath:jdbc.properties")
public class MyBatisConfig {

    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    //配置连接池
    @Bean
    public DataSource getDs(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource getDs){
        DataSourceTransactionManager tm = new DataSourceTransactionManager();
        //接管数据源对象
        tm.setDataSource(getDs);
        return tm;
    }


    //向spring容器中添加一个SqlSessionFactory对象
    @Bean
    public SqlSessionFactoryBean ssfb(DataSource getDs){
        SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();

        //替代mybatis的核心配置文件
        //配置包别名
        ssfb.setTypeAliasesPackage("com.qf.pojo");

        Configuration config = new Configuration();
        //支持驼峰命名
        config.setMapUnderscoreToCamelCase(true);
        //配置日志输出
        config.setLogImpl(StdOutImpl.class);

        ssfb.setConfiguration(config);

        //设置分页插件
        Interceptor pageInterceptor = new PageInterceptor();
        Properties pro = new Properties();
        //设置数据库的方言
        pro.setProperty("helperDialect","mysql");
        //设置错误页码的修正
        pro.setProperty("reasonable","true");
        pageInterceptor.setProperties(pro);
        ssfb.setPlugins(pageInterceptor);

        //设置数据源，获取连接
        ssfb.setDataSource(getDs);
        return ssfb;
    }

    /*
        向spring容器中添加一个MapperScannerConfigurer
            这个对象是要给Bean工厂的后置处理器,能够动态向spring容器中添加一些BeanDefinition信息,进一步会将这种BeanDefinition信息变成spring容器中的bean对象
            *** 注意：工厂的后置处理器的执行必须优先于所有spring bean

            java对象： .java--.class--ClassLoader--Class--实例对象（java bean）
            spring ioc对象：.java--.class--ClassLoader--Class--BeanDefinition--实例对象（spring bean）
     */
    @Bean
    public static MapperScannerConfigurer msc(){
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        //告诉msc，mapper映射接口在哪里
        msc.setBasePackage("com.qf.mapper");
        return msc;
    }
}
